package com.mworld.galaxy.bull.service.product;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;
import org.springside.modules.persistence.SearchFilter.Operator;

import com.mworld.galaxy.bull.entity.StatefulIdEntity;
import com.mworld.galaxy.bull.entity.product.Category;
import com.mworld.galaxy.bull.repository.product.CategoryDao;
import com.mworld.galaxy.bull.repository.product.LinkDao;

@Component
@Transactional(readOnly = true)
public class CategoryService {

    public static final int MAX_CATEGORY_NUM_IN_SHOP = 100;

    @Autowired
    private CategoryDao categoryDao;
    @Autowired
    private LinkDao linkDao;

    public Category getCategory(Long id) {
        return categoryDao.findOne(id);
    }

    public Category getCategory(String id) {
        try {
            return getCategory(Long.parseLong(id));
        } catch (Exception err) {
            return null;
        }
    }

    public Category getCategoryByName(String name) {
        return categoryDao.findByName(name);
    }

    public Page<Category> getShopCategory(Long shopId) {
        PageRequest pageRequest = new PageRequest(0, MAX_CATEGORY_NUM_IN_SHOP, new Sort(Direction.ASC, "order"));
        Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
        filters.put("shop.id", new SearchFilter("shop.id", Operator.EQ, shopId));
        filters.put("status", new SearchFilter("status", Operator.LT, StatefulIdEntity.STATUS_DELETED));
        Specification<Category> spec = DynamicSpecifications.bySearchFilter(filters.values(), Category.class);
        return categoryDao.findAll(spec, pageRequest);
    }

    @Transactional(readOnly = false)
    public void saveCategory(Category category) {
        categoryDao.save(category);
    }

    @Transactional(readOnly = false)
    public void deleteCategory(Long id) {
        Category category = categoryDao.findOne(id);
        if (category == null) {
            return;
        }
        List<Category> c = null;
        switch (category.getLevel()) {
        case 1:
            categoryDao.changeStatusFromLevel1(id, StatefulIdEntity.STATUS_DELETED);
            c = getCategoryListByLevel1Id(id);
            // linkDao.deleteLevel1CategoryLink(id);
            break;
        case 2:
            categoryDao.changeStatusFromLevel2(id, StatefulIdEntity.STATUS_DELETED);
            c = getCategoryListByLevel2Id(id);
            // linkDao.deleteLevel2CategoryLink(id);
            break;
        case 3:
            categoryDao.changeStatus(id, StatefulIdEntity.STATUS_DELETED);
            c = new ArrayList<Category>();
            c.add(category);
            // linkDao.deleteCategoryLink(id);
            break;
        }
        if (c != null) {
            for (int i = 0; i < c.size(); i++) {
                linkDao.deleteCategoryLink(c.get(i).getId());
            }
        }
    }

    private List<Category> getCategoryListByLevel1Id(Long id) {
        PageRequest pageRequest = new PageRequest(0, 100, new Sort(Direction.ASC, "name"));
        Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
        filters.put("", new SearchFilter("level1Id", Operator.EQ, id));
        Specification<Category> spec = DynamicSpecifications.bySearchFilter(filters.values(), Category.class);
        Page<Category> category = categoryDao.findAll(spec, pageRequest);
        return category.getContent();
    }

    private List<Category> getCategoryListByLevel2Id(Long id) {
        PageRequest pageRequest = new PageRequest(0, 100, new Sort(Direction.ASC, "name"));
        Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
        filters.put("", new SearchFilter("level2Id", Operator.EQ, id));
        Specification<Category> spec = DynamicSpecifications.bySearchFilter(filters.values(), Category.class);
        Page<Category> category = categoryDao.findAll(spec, pageRequest);
        return category.getContent();
    }
}
